home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * edge.c
- *
- * This program will read in an image file, apply a simple edge detection
- * algorithm to it and then write out the resulting file. It demonstrates
- * the use of color on the output file to indicate edges.
- *
- * Usage edge input.image output.image threshold
- *
- * At all pixels where there is a difference equal to or greater than
- * "threshold" that pixel will be set to red. Other pixels left intact.
- *
- * This program is based on the Sobel edge detection algorithm, it uses the
- * fact that objects in an image are usually delineated by sharp changes in
- * intensity. The image is processed by picking 8 adjacent pixels and treating
- * them as a 3 X 3 array. The array can be represented as follows :
- *
- * | a b c |
- * | d e f |
- * | g h i |
- *
- * And there are four unique straightline paths through this array which pass
- * through the center pixel. They can be represented as :
- *
- * g -> e -> c
- * d -> e -> f
- * a -> e -> i
- * b -> e -> h
- *
- * The algorithm treats the three pixels as points on a line described by the
- * function : Intensity = M * x + C. The parameter of interest is the slope
- * of the function M. The sharper the transition in intensity, the larger the
- * value of the slope. This is compared to the threshold and if it exceeds it
- * the pixel e is considered to lie on an edge and is marked as such.
- *
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <stdio.h>
- #include <fcntl.h>
-
- /* This array describes the relative offsets of adjacent pixels that make up
- * the edge of interest.
- */
- static int edges[] = {
- -1, 1, 1,-1, /* g and c */
- -1, 0, 1, 0, /* d and f */
- -1,-1, 1, 1, /* a and i */
- 0,-1, 0, 1 /* b and h */
- };
-
-
- void main(argc,argv)
- int argc;
- char *argv[];
-
- {
- UBYTE *image,*simage; /* An array for our image */
- USHORT colors[16]; /* The color map */
- int i,ii,j, /* Some counters */
- thresh, /* The edge threshold */
- edgepixels, /* The number of edge pixels found */
- x,y,m,p1,p2, /* Image coordinates */
- x1,x2,y1,y2; /* Edge boundary coordinates */
-
-
- printf("Simple edge analysis program.\n");
- if (argc != 4) {
- printf("usage is Edge infile outfile threshold\n");
- exit(10);
- }
- thresh = atoi(argv[3]);
- if ((thresh < 0) || (thresh > 15)) {
- printf("Illegal threshold value, use a number between 0 and 15\n");
- exit(10);
- }
- printf("Using Threshold value %d.\n",thresh);
-
- /* Buffer for one image + 4 lines. The algorithm below will store the
- * resulting image into the image buffer - 4 lines. That way we do not
- * need to allocate two complete image buffers. The allocate call will
- * also set the array to zero.
- */
- image = (UBYTE *)AllocMem(129280,MEMF_CLEAR);
-
- if (image == NULL) {
- printf("Sorry couldn't allocate the image buffer! \n");
- exit(10);
- }
- simage = image + 1280; /* Source image resides four lines below image */
-
- /* First we read in the source image */
- i = ReadImage(argv[1],simage,colors);
- if (i != 0) {
- printf("Error reading in the source image.\n");
- FreeMem(image,129280);
- exit(10);
- }
-
- /* Now do what ever image processing we wish on the image data */
-
- printf("Processing the source image \n");
- edgepixels = 0;
- /* First copy the first row of pixels to the destination */
- for (i=0; i<640; i++) {
- j = Pixel(simage,i,0) - 1;
- if ((j < 0) || (j > 14)) j = 0;
- SetPixel(image,i,0,j);
- }
- for (y=1; y<399; y++) {
- printf("Line %d\x0d",y);
- /* Move a line from the Source image to the Destination Image */
- for (i=0; i<640; i++) {
- j = Pixel(simage,i,y) - 1;
- if ((j < 0) || (j > 14)) j = 0;
- SetPixel(image,i,y,j);
- }
- /* Now analyze each pixel in this line */
- for (x=1; x<639; x++) {
- /* (x,y) is the center pixel in a 3X3 square */
- chkabort(); /* Added in case the user wants to abort */
- for (j=0; j<4; j++) { /* Check for four types of edges */
- /* Note the indirection through the color map since Pixel returns
- * the colormap entry this pixel uses, the colormap actually
- * contains its intensity. Also since all color map entries are
- * shades of gray R = G = B and the intensity is logically ANDed
- * to mask off the R and G components leaving only the B value
- * which will always be between 0 and 15.
- */
- x1 = x + edges[j*4];
- y1 = y + edges[j*4+1];
- x2 = x + edges[j*4+2];
- y2 = y + edges[j*4+3];
- p1 = colors[Pixel(simage,x2,y2)] & 0xf;
- p2 = colors[Pixel(simage,x1,y1)] & 0xf;
- m = abs(p1 - p2);
- if (m > thresh) {
- edgepixels++;
- SetPixel(image,x,y,15);
- break;
- } /* if we crossed the threshold */
- } /* for each value of j */
- } /* For x */
- } /* for y */
- printf("\n Done.\n");
- printf(" Set the value for %d edge pixels\n",edgepixels);
- /* Now we fix up the color map because we have shifted all of the pixels
- * down by one in the color map to make room for our edge color (red)
- */
- for (i=1; i<15; i++) colors[i-1] = colors[i];
- colors[15] = 0x0f00; /* Set edge pixels to red */
- /* Then we write out the image */
- i = WriteImage(argv[2],image,colors);
- if (i != 0) printf("Error writing the output file!\n");
- FreeMem(image,129280);
- exit(i);
- }
-
-